package cn.jolyoulu.common.core.queue.delayed;

import lombok.Getter;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * @Author: JolyouLu
 * @Date: 2023/4/15 18:43
 * @Description 延迟任务的内容
 */
@Getter
public final class DelayedTaskEntity<T> implements Delayed {

    /**
     * 任务id
     */
    private final String taskId;
    /**
     * 任务执行的时间点
     */
    private final LocalDateTime exTime;
    /**
     * 任务的创建时间
     */
    private final LocalDateTime creatTime;
    /**
     * 任务参数
     */
    private final T task;
    /**
     * 任务class
     */
    private final Class<T> tClass;

    /**
     * 构建一个延迟任务
     * @param taskId 任务ID，幂等性任务时需要用到
     * @param exTime 执行的时间点
     * @param task 携带的参数
     */
    @SuppressWarnings("unchecked")
    public DelayedTaskEntity(String taskId, LocalDateTime exTime, T task) {
        this.taskId = taskId;
        this.exTime = exTime;
        this.creatTime = LocalDateTime.now();
        this.task = task;
        this.tClass = (Class<T>) task.getClass();
    }

    @Override
    public long getDelay(TimeUnit unit) {
        if (Objects.isNull(unit)){
            throw new NullPointerException("unit is not null");
        }
        return Duration.between(LocalDateTime.now(), exTime).toNanos();
    }

    @Override
    public int compareTo(Delayed o) {
        if (Objects.isNull(o)){
            throw new NullPointerException("Delayed is not null");
        }
        if (o instanceof DelayedTaskEntity){
            DelayedTaskEntity<T> task = (DelayedTaskEntity<T>) o;
            if (exTime.equals(task.getExTime())){
                return 0;
            }else if (exTime.isAfter(task.getExTime())){
                return 1;
            }else {
                return -1;
            }
        }
        return 0;
    }
}
